package cn.org.intelli.zffserver.controller;

import cn.org.intelli.zffserver.aop.AuthenticationTicket;
import cn.org.intelli.zffserver.domain.BackBean;
import cn.org.intelli.zffserver.entity.*;
import cn.org.intelli.zffserver.repository.*;
import cn.org.intelli.zffserver.service.JobService;
import cn.org.intelli.zffserver.util.Uid;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import dm.jdbc.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.query.Param;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping({"/model"})
@Slf4j
public class ModelController {

    @Autowired
    private ModelRepository modelRepository;

    @Autowired
    private JobRepository jobRepository;

    @Autowired
    private JobService jobService;

    @Autowired
    private DataBaseV2Repository dataBasev2Repository;

    @Autowired
    private ExecutorProgramRepository executorProgramRepository;

    @Autowired
    private ModelPeggingMapRepository modelPeggingMapRepository;

    @GetMapping({"/getModelDetailByJobId"})
    public BackBean<ModelEntity> getModelDetailByJobId(@RequestParam("jobId") String jobId) {
        try {
            /*  56 */
            JobEntity job = this.jobRepository.findById(jobId).get();
            /*  57 */
            String modelId = job.getModelId();
            /*  58 */
            ModelEntity model = this.modelRepository.findById(modelId).get();
            /*  59 */
            return BackBean.<ModelEntity>builder().status(true).data(model).build();
            /*  60 */
        } catch (Exception e) {
            /*  61 */
            e.printStackTrace();
            /*  62 */
            log.error("@GetModelDetailByJobId: error is {}", e.getMessage());
            /*  63 */
            return BackBean.<ModelEntity>builder().status(false).message(e.getMessage()).build();
        }
    }


    @GetMapping({"/getModelPeggings"})
    public BackBean<JSONArray> getModelPeggings(@RequestParam("modelId") String modelId) {
        try {
            /*  75 */
            List<ModelPeggingMapEntity> peggings = this.modelPeggingMapRepository.findAllByModelId(modelId);
            /*  76 */
            JSONArray result = new JSONArray();

            /*  78 */
            JSONObject cache = new JSONObject();
            /*  79 */
            peggings.forEach(pegging -> {
                String columnName = pegging.getColumnName();

                String scriptId = pegging.getScriptId();

                String scriptType = pegging.getScriptType();

                JSONObject aatom = new JSONObject();
                aatom.put("scriptId", scriptId);
                aatom.put("scriptType", scriptType);
                if (cache.containsKey(columnName)) {
                    JSONArray atom = cache.getJSONArray(columnName);
                    atom.add(aatom);
                } else {
                    JSONArray atom = new JSONArray();
                    atom.add(aatom);
                    cache.put(columnName, atom);
                }
            });
            /*  98 */
            for (Map.Entry entry : cache.entrySet()) {
                /*  99 */
                String key = entry.getKey().toString();
                /* 100 */
                JSONObject atom = new JSONObject();
                /* 101 */
                atom.put(key, cache.getJSONArray(key));
                /* 102 */
                result.add(atom);
            }

            /* 105 */
            return BackBean.<JSONArray>builder().status(true).data(result).build();
            /* 106 */
        } catch (Exception e) {
            /* 107 */
            e.printStackTrace();
            /* 108 */
            log.error("@GetModelPeggings: error is {}", e.getMessage());
            /* 109 */
            return BackBean.<JSONArray>builder().status(false).message(e.getMessage()).build();
        }
    }


    @GetMapping({"/getModelDetail"})
    public BackBean<ModelEntity> getModelDetail(@RequestParam("modelId") String modelId) {
        try {
            /* 121 */
            ModelEntity modelEntity = this.modelRepository.findById(modelId).get();
            /* 122 */
            return BackBean.<ModelEntity>builder().status(true).data(modelEntity).build();
            /* 123 */
        } catch (Exception e) {
            /* 124 */
            e.printStackTrace();
            /* 125 */
            log.error("@GetModelDetail: error is {}", e.getMessage());
            /* 126 */
            return BackBean.<ModelEntity>builder().status(false).message(e.getMessage()).build();
        }
    }


    @GetMapping({"/getModelDetail4Html"})
    public BackBean<JSONObject> getModelDetail4Html(@RequestParam("modelId") String modelId) {
        try {
            /* 138 */
            ModelEntity modelEntity = this.modelRepository.findById(modelId).get();
            /* 139 */
            JSONObject result = JSON.parseObject(JSON.toJSONString(modelEntity));
            /* 140 */
            result.put("paramMeta", JSONArray.parseArray(modelEntity.getParamMeta()));
            /* 141 */
            result.put("resultMeta", JSONArray.parseArray(modelEntity.getResultMeta()));
            /* 142 */
            result.put("defaultParam", JSONObject.parseObject(modelEntity.getDefaultParam()));
            /* 143 */
            return BackBean.<JSONObject>builder().status(true).data(result).build();
            /* 144 */
        } catch (Exception e) {
            /* 145 */
            e.printStackTrace();
            /* 146 */
            log.error("@GetModelDetail: error is {}", e.getMessage());
            /* 147 */
            return BackBean.<JSONObject>builder().status(false).message(e.getMessage()).build();
        }
    }


    @PostMapping({"/createModel"})
    public BackBean<String> createModel(@RequestBody JSONObject modelJson) {
        try {
            /* 161 */
            ModelEntity modelEntity = JSON.toJavaObject(modelJson, ModelEntity.class);


            /* 164 */
            if (StringUtil.isEmpty(modelEntity.getModelCode())) {
                /* 165 */
                throw new Exception("Model code can not be null!");
            }





            /* 172 */
            String modelCode = modelEntity.getModelCode();
            /* 173 */
            if (!modelCode.matches("^[a-zA-Z].*")) {
                /* 174 */
                throw new Exception("Model code should be started with zimu");
            }
            /* 176 */
            String executorProgramId = modelEntity.getExecutorProgramId();
            /* 177 */
            if (StringUtil.isEmpty(executorProgramId)) {
                /* 178 */
                throw new Exception("执行程序未配置");
            }

            /* 181 */
            ExecutorProgramEntity program = this.executorProgramRepository.findById(executorProgramId).get();
            /* 182 */
            modelEntity.setModelExecuter(program.getExecutorName());
            /* 183 */
            modelEntity.setExecutorId(program.getExecutorJarId());


            /* 186 */
            if (StringUtil.isEmpty(modelEntity.getModelExecuter()) ||
                    /* 187 */         StringUtil.isEmpty(modelEntity.getSourceDbId()) ||
                    /* 188 */         StringUtil.isEmpty(modelEntity.getDestinationDbId())) {
                /* 189 */
                throw new Exception("源数据源、目标数据源、执行器未正确配置");
            }
            /* 191 */
            DataBaseV2Entity database = this.dataBasev2Repository.findById(modelEntity.getDestinationDbId()).get();

            /* 193 */
            String destinationDbSchema = JSON.parseObject(database.getDbInfo()).getString("schemaName");
            /* 194 */
            if (StringUtil.isEmpty(destinationDbSchema)) {
                /* 195 */
                throw new Exception("目标数据源模式（数据库）名称不能为空!");
            }

            /* 198 */
            String uid = Uid.generateShortUuid();
            /* 199 */
            modelEntity.setId(uid);
            /* 200 */
            modelEntity.setCreateTime(new Date());
            /* 201 */
            modelEntity.setUpdateTime(new Date());
            /* 202 */
            String userPin = AuthenticationTicket.getTicket().getPin();

            /* 204 */
            if (StringUtil.isNotEmpty(modelEntity.getSql())) {
                /* 205 */
                modelEntity.setSql(modelEntity.getSql());
            }
            /* 207 */
            if (StringUtil.isNotEmpty(modelEntity.getDefaultParam())) {
                /* 208 */
                modelEntity.setDefaultParam(modelEntity.getDefaultParam());
            }
            /* 210 */
            if (StringUtil.isNotEmpty(modelEntity.getResultMeta())) {
                /* 211 */
                modelEntity.setResultMeta(modelEntity.getResultMeta());
            }
            /* 213 */
            if (StringUtil.isNotEmpty(modelEntity.getParamMeta())) {
                /* 214 */
                modelEntity.setParamMeta(modelEntity.getParamMeta());
            }

            /* 217 */
            modelEntity.setUserPin(userPin);
            /* 218 */
            this.modelRepository.save(modelEntity);
            /* 219 */
            return BackBean.<String>builder().status(true).data("success").build();
            /* 220 */
        } catch (Exception e) {
            /* 221 */
            e.printStackTrace();
            /* 222 */
            log.error("@CreateModelDetail: error is {}", e.getMessage());
            /* 223 */
            return BackBean.<String>builder().status(false).message(e.getMessage()).build();
        }
    }


    @PostMapping({"/updateModel/{modelId}"})
    public BackBean<String> updateModel(@PathVariable("modelId") String modelId, @RequestBody JSONObject modelJson) {
        try {
            /* 237 */
            ModelEntity modelEntity = JSON.toJavaObject(modelJson, ModelEntity.class);

            /* 239 */
            ModelEntity oriModel = this.modelRepository.findById(modelId).get();
            /* 240 */
            if (StringUtils.isNotEmpty(modelEntity.getDefaultParam())) {
                /* 241 */
                oriModel.setDefaultParam(modelEntity.getDefaultParam());
            }
            /* 243 */
            if (StringUtils.isNotEmpty(modelEntity.getDescription())) {
                /* 244 */
                oriModel.setDescription(modelEntity.getDescription());
            }
            /* 246 */
            if (StringUtils.isNotEmpty(modelEntity.getModelCode())) {





                /* 253 */
                oriModel.setModelCode(modelEntity.getModelCode());
            }
            /* 255 */
            if (StringUtils.isNotEmpty(modelEntity.getExecutorProgramId())) {

                /* 257 */
                ExecutorProgramEntity program = this.executorProgramRepository.findById(modelEntity.getExecutorProgramId()).get();
                /* 258 */
                oriModel.setExecutorProgramId(modelEntity.getExecutorProgramId());
                /* 259 */
                oriModel.setModelExecuter(program.getExecutorName());
                /* 260 */
                oriModel.setExecutorId(program.getExecutorJarId());
            }
            /* 262 */
            if (StringUtils.isNotEmpty(modelEntity.getModelName())) {
                /* 263 */
                oriModel.setModelName(modelEntity.getModelName());
            }
            /* 265 */
            if (StringUtils.isNotEmpty(modelEntity.getModelType())) {
                /* 266 */
                oriModel.setModelType(modelEntity.getModelType());
            }
            /* 268 */
            if (StringUtils.isNotEmpty(modelEntity.getRecord())) {
                /* 269 */
                oriModel.setRecord(modelEntity.getRecord());
            }
            /* 271 */
            if (StringUtils.isNotEmpty(modelEntity.getResultMeta())) {
                /* 272 */
                oriModel.setResultMeta(modelEntity.getResultMeta());
            }
            /* 274 */
            if (StringUtils.isNotEmpty(modelEntity.getSql())) {
                /* 275 */
                oriModel.setSql(modelEntity.getSql());
            }
            /* 277 */
            if (StringUtils.isNotEmpty(modelEntity.getScope())) {
                /* 278 */
                oriModel.setScope(modelEntity.getScope());
            }
            /* 280 */
            if (StringUtils.isNotEmpty(modelEntity.getParamMeta())) {
                /* 281 */
                oriModel.setParamMeta(modelEntity.getParamMeta());
            }
            /* 283 */
            if (StringUtils.isNotEmpty(modelEntity.getTags())) {
                /* 284 */
                oriModel.setTags(modelEntity.getTags());
            }
            /* 286 */
            if (StringUtils.isNotEmpty(modelEntity.getDestinationDbId())) {
                /* 287 */
                oriModel.setDestinationDbId(modelEntity.getDestinationDbId());
            }
            /* 289 */
            if (StringUtils.isNotEmpty(modelEntity.getSourceDbId())) {
                /* 290 */
                oriModel.setSourceDbId(modelEntity.getSourceDbId());
            }
            /* 292 */
            oriModel.setUpdateTime(new Date());
            /* 293 */
            this.modelRepository.save(oriModel);
            /* 294 */
            return BackBean.<String>builder().status(true).data("success").build();
            /* 295 */
        } catch (Exception e) {
            /* 296 */
            e.printStackTrace();
            /* 297 */
            log.error("@UpdateModel: error is {}", e.getMessage());
            /* 298 */
            return BackBean.<String>builder().status(false).message(e.getMessage()).build();
        }
    }


    @PostMapping({"/deleteModel/{modelId}"})
    public BackBean<String> deleteModel(@PathVariable("modelId") String modelId) {
        try {
            /* 311 */
            List<JobEntity> jobEntities = this.jobRepository.findAllByModelId(modelId);
            /* 312 */
            this.jobService.deleteJobs(jobEntities);


            /* 315 */
            this.modelRepository.deleteById(modelId);
            /* 316 */
            return BackBean.<String>builder().status(true).data("success").build();
            /* 317 */
        } catch (Exception e) {
            /* 318 */
            e.printStackTrace();
            /* 319 */
            log.error("@DeleteModel: error is {}", e.getMessage());
            /* 320 */
            return BackBean.<String>builder().status(false).message(e.getMessage()).build();
        }
    }


    @GetMapping({"/getModelList"})
    public BackBean<JSONArray> getModelList(@RequestParam(name = "page", defaultValue = "1") Integer page, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, @Param("modelName") String modelName) {
        try {
            /* 333 */
            String userPin = AuthenticationTicket.getTicket().getPin();
            /* 334 */
            Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "createTime"));
            /* 335 */
            PageRequest pageRequest = PageRequest.of(page.intValue() - 1, pageSize.intValue(), sort);
            /* 336 */
//            Page<ModelEntity> modelPage = this.modelRepository.findAll((Specification) new Object(this, userPin, modelName), (Pageable) pageRequest);
            // 使用 Specification 进行动态查询
            Specification<ModelEntity> specification = (root, query, criteriaBuilder) -> {
                List<Predicate> predicates = new ArrayList<>();

                // 用户权限过滤
                predicates.add(criteriaBuilder.equal(root.get("userPin"), userPin));

                // 模型名称模糊查询
                if (StringUtils.isNotBlank(modelName)) {
                    predicates.add(criteriaBuilder.like(root.get("modelName"), "%" + modelName + "%"));
                }

                return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
            };

            Page<ModelEntity> modelPage = this.modelRepository.findAll(specification, pageRequest);

            /* 352 */
            JSONArray result = new JSONArray();
            /* 353 */
            modelPage.getContent().forEach(model -> {
                JSONObject atom = JSON.parseObject(JSON.toJSONString(model));

                atom.put("defaultParam", JSON.parseObject(model.getDefaultParam()));
                atom.put("resultMeta", JSONArray.parseArray(model.getResultMeta()));
                atom.put("paramMeta", JSONArray.parseArray(model.getParamMeta()));
                result.add(atom);
            });
            /* 361 */
            return BackBean.<JSONArray>builder()
/* 362 */.status(true)
/* 363 */.totalNum(Long.valueOf(modelPage.getTotalElements()))
/* 364 */.data(result).build();
            /* 365 */
        } catch (Exception e) {
            /* 366 */
            e.printStackTrace();
            /* 367 */
            log.error("@GetModelList: error is {}", e.getMessage());
            /* 368 */
            return BackBean.<JSONArray>builder().status(false).message(e.getMessage()).build();
        }
    }


    @PostMapping({"/createModelPeggingMap"})
    public BackBean<String> createModelPeggingMap(@RequestBody JSONObject param) {
        try {
            /* 380 */
            String modelId = param.getString("modelId");
            /* 381 */
            String columnName = param.getString("columnName");
            /* 382 */
            String countScriptId = param.getString("countScriptId");
            /* 383 */
            String dataScriptId = param.getString("dataScriptId");


            /* 386 */
            List<ModelPeggingMapEntity> pegging = this.modelPeggingMapRepository.findAllByModelIdAndColumnName(modelId, columnName);
            /* 387 */
            if (pegging != null && pegging.size() > 0) {
                /* 388 */
                this.modelPeggingMapRepository.deleteAll(pegging);
            }

            /* 391 */
            ModelPeggingMapEntity countPegging = new ModelPeggingMapEntity();
            /* 392 */
            countPegging.setId(Uid.generateShortUuid());
            /* 393 */
            countPegging.setModelId(modelId);
            /* 394 */
            countPegging.setColumnName(columnName);
            /* 395 */
            countPegging.setScriptType("COUNT");
            /* 396 */
            countPegging.setScriptId(countScriptId);

            /* 398 */
            ModelPeggingMapEntity dataPegging = new ModelPeggingMapEntity();
            /* 399 */
            dataPegging.setId(Uid.generateShortUuid());
            /* 400 */
            dataPegging.setModelId(modelId);
            /* 401 */
            dataPegging.setColumnName(columnName);
            /* 402 */
            dataPegging.setScriptType("DATA");
            /* 403 */
            dataPegging.setScriptId(dataScriptId);

            /* 405 */
            this.modelPeggingMapRepository.save(countPegging);
            /* 406 */
            this.modelPeggingMapRepository.save(dataPegging);

            /* 408 */
            return BackBean.<String>builder().status(true).data("success").build();
            /* 409 */
        } catch (Exception e) {
            /* 410 */
            e.printStackTrace();
            /* 411 */
            log.error("@CreateModelPeggingMap: error is {}");
            /* 412 */
            return BackBean.<String>builder().status(false).message(e.getMessage()).build();
        }
    }


    private ModelEntity modelEncode(ModelEntity model) throws Exception {
        /* 422 */
        if (StringUtil.isNotEmpty(model.getSql())) {
            /* 423 */
            model.setSql(URLEncoder.encode(model.getSql(), "UTF-8"));
        }
        /* 425 */
        if (StringUtil.isNotEmpty(model.getDefaultParam())) {
            /* 426 */
            model.setDefaultParam(URLEncoder.encode(model.getDefaultParam(), "UTF-8"));
        }
        /* 428 */
        if (StringUtil.isNotEmpty(model.getResultMeta())) {
            /* 429 */
            model.setResultMeta(URLEncoder.encode(model.getResultMeta(), "UTF-8"));
        }
        /* 431 */
        if (StringUtil.isNotEmpty(model.getParamMeta())) {
            /* 432 */
            model.setParamMeta(URLEncoder.encode(model.getParamMeta(), "UTF-8"));
        }
        /* 434 */
        return model;
    }
}

 